package com.xue;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author xuejingbao
 * @create 2023-01-13 16:39
 */
public class Main {

    public static void main(String[] args) {
        List<Node> nodes = Arrays.asList(new Node(1, "管理部", 0),
                new Node(3, "信息部", 2),
                new Node(4, "人事部", 2),
                new Node(2, "财务部", 1),
                new Node(5, "我", 3),
                new Node(6, "老婆", 4),
                new Node(6, "总经办", 1)
        );

        System.out.println(">>>>>>形成树结构>>>>>>");
        long start = System.currentTimeMillis();
        List<Node> treeNode = nodes.stream().filter(node -> node.getFatherId() == 0)
                .map(node -> tree(node, nodes)).collect(Collectors.toList());
        System.out.println("耗时：" + (System.currentTimeMillis() - start));
        System.out.println(JSONUtil.toJsonStr(treeNode));

        start = System.currentTimeMillis();
        Map<Integer, List<Node>> nodeMap = nodes.stream().collect(Collectors.groupingBy(Node::getFatherId));
        List<Node> fastTreeNode = nodeMap.get(0).stream().map(node -> fastTree(node, nodeMap)).collect(Collectors.toList());
        System.out.println("耗时：" + (System.currentTimeMillis() - start));
        System.out.println(JSONUtil.toJsonStr(fastTreeNode));

        System.out.println(">>>>>>显示所有叶子节点，即没孩子的，无论层级>>>>>>");
        Node packTreeNode = new Node();
        packTreeNode.setNodeId(-1);
        packTreeNode.setChildren(treeNode);
        List<Node> leafNode = leafNode(packTreeNode);
        System.out.println(JSONUtil.toJsonStr(leafNode));

        System.out.println(">>>>>>返回4层的节点>>>>>>");
        List<Node> levelNode = levelNode(treeNode, 4, 1);
        System.out.println(JSONUtil.toJsonStr(levelNode));

        System.out.println(">>>>>>树的深度>>>>>>");
        int treeDepth = treeDepth(treeNode);
        System.out.println("树的深度：" + treeDepth);

        System.out.println(">>>>>>根据nodeId获取节点>>>>>>");
        Node nodeById = getNodeById(packTreeNode, 6);
        System.out.println("根据nodeId获取节点："+nodeById);

    }

    /**
     * 形成树
     *
     * @param node
     * @param nodes
     * @return
     */
    private static Node tree(Node node, List<Node> nodes) {
        List<Node> childrenList = nodes.stream().filter(nodeItem -> nodeItem.getFatherId().equals(node.getNodeId()))
                .map(nodeItem -> tree(nodeItem, nodes))
                .collect(Collectors.toList());
        node.setChildren(childrenList);
        return node;
    }

    /**
     * 快速形成树
     *
     * @param node
     * @param nodeMap
     * @return
     */
    private static Node fastTree(Node node, Map<Integer, List<Node>> nodeMap) {
        List<Node> nodes = nodeMap.get(node.getNodeId());
        if (ObjectUtil.isEmpty(nodes)) {
            return node;
        }
        List<Node> children = nodes.stream()
                .map(nodeItem -> fastTree(nodeItem, nodeMap))
                .collect(Collectors.toList());
        node.setChildren(children);
        return node;
    }

    /**
     * 显示所有叶子节点，即没孩子的，无论层级
     *
     * @param node
     * @return
     */
    private static List<Node> leafNode(Node node) {
        if (ObjectUtil.isEmpty(node.getChildren())) {
            return Arrays.asList(node);
        }
        return node.getChildren().stream().map(item -> leafNode(item))
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    }

    /**
     * 返回某层级下的节点
     *
     * @param nodeList
     * @param level
     * @param count
     * @return
     */
    private static List<Node> levelNode(List<Node> nodeList, Integer level, Integer count) {
        if (count.equals(level)) {
            return nodeList;
        }
        final int nextCount = ++count;
        return nodeList.stream().map(node -> levelNode(node.getChildren(), level, nextCount))
                .flatMap(Collection::stream).collect(Collectors.toList());
    }

    /**
     * 树深度
     *
     * @param nodeList
     * @return
     */
    private static int treeDepth(List<Node> nodeList) {
        if (ObjectUtil.isEmpty(nodeList)) {
            return 0;
        }
        return nodeList.stream().map(node -> treeDepth(node.getChildren())).max(Integer::compare).get() + 1;
    }


    /**
     * 根据nodeId获取对应的下面结构
     *
     * @param node
     * @param id
     * @return
     */
    private static Node getNodeById(Node node, int id) {
        if (null == node) {
            return null;
        } else {
            if (node.getNodeId().equals(id)) {
                return node;
            } else {
                List<Node> childList = node.getChildren();
                if (null != childList) {
                    for (Node child : childList) {
                        Node result = getNodeById(child, id);
                        if (result != null) {
                            return result;
                        }
                    }
                }
                return null;
            }
        }
    }


}
